using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using CR.Domain.DbContext;
using CR.Infrastructure;
using CR.Infrastructure.Repositories;
using CR.API.Services;
using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Reflection;
using Microsoft.AspNetCore.Http;
using CR.Application.Services;
using CR.Application.Interfaces;
using CR.Application.Mappings;
using CR.Domain.Entities;
using Microsoft.Extensions.Logging;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
// 添加框架服务
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddHttpContextAccessor();
builder.Services.AddMemoryCache(); // 添加内存缓存
builder.Services.AddHttpClient(); // 添加HTTP客户端

// 添加AutoMapper服务
builder.Services.AddAutoMapper(typeof(CR.Application.Mappings.MappingProfile));

// 添加数据库上下文
builder.Services.AddDbContext<TraceabilityDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"),
    sqlServerOptions => sqlServerOptions.EnableRetryOnFailure()));

// 添加仓储
builder.Services.AddScoped(typeof(IBaseRepository<>), typeof(BaseRepository<>));
builder.Services.AddScoped<IBreedingInfoRepository, BreedingInfoRepository>();
builder.Services.AddScoped<ITraceabilityRepository, TraceabilityRepository>();
builder.Services.AddScoped<IUserRepository, UserRepository>();

// 添加服务
builder.Services.AddScoped<IJwtService, JwtService>();
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<ICaptchaService, CloudCaptchaService>();
builder.Services.AddScoped<ITraceabilityService, TraceabilityService>();
builder.Services.AddScoped<IBreedingInfoService, BreedingInfoService>();
builder.Services.AddScoped<IProductInspectionReportService, ProductInspectionReportService>();

// 注册HttpContextAccessor
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

// 配置JWT认证
var jwtSettings = builder.Configuration.GetSection("Jwt");
var secretKey = jwtSettings["SecretKey"] ?? "ColdRabbit_SecurityKey_MustBeVeryLongAndSecure!2025";
var key = Encoding.ASCII.GetBytes(secretKey);
builder.Services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
    x.RequireHttpsMetadata = false;
    x.SaveToken = true;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(key),
        ValidateIssuer = true,
        ValidIssuer = jwtSettings["Issuer"] ?? "ColdRabbitAPI",
        ValidateAudience = true,
        ValidAudience = jwtSettings["Audience"] ?? "ColdRabbitClient",
        ValidateLifetime = true,
        ClockSkew = TimeSpan.Zero
    };
});

// 添加Swagger
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo
    {
        Title = "ColdRabbit API",
        Version = "v1",
        Description = "ColdRabbit 溯源系统API文档",
        Contact = new OpenApiContact
        {
            Name = "ColdRabbit Team"
        }
    });
    
    // 添加JWT认证配置
    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey,
        Scheme = "Bearer"
    });

    c.AddSecurityRequirement(new OpenApiSecurityRequirement()
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                },
                Scheme = "oauth2",
                Name = "Bearer",
                In = ParameterLocation.Header,
            },
            new List<string>()
        }
    });
    
    // 启用XML注释
    var xmlFiles = Directory.GetFiles(AppContext.BaseDirectory, "*.xml");
    foreach (var xmlFile in xmlFiles)
    {
        c.IncludeXmlComments(xmlFile, includeControllerXmlComments: true);
    }
});

// 配置跨域策略
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAll", builder =>
    {
        builder.AllowAnyOrigin()
               .AllowAnyMethod()
               .AllowAnyHeader();
    });
    
    options.AddPolicy("ProductionCors", builder =>
    {
        builder.WithOrigins("http://localhost:5173", "https://localhost:5173") // 允许的前端源
               .AllowAnyMethod()
               .AllowAnyHeader()
               .AllowCredentials();
    });
});

// 创建必要的上传目录
var webRootPath = builder.Environment.WebRootPath;
if (string.IsNullOrEmpty(webRootPath))
{
    webRootPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");
    Directory.CreateDirectory(webRootPath);
}

var uploadDirs = new[]
{
    Path.Combine(webRootPath, "captcha"),
    Path.Combine(webRootPath, "uploads", "images")
};

foreach (var dir in uploadDirs)
{
    if (!Directory.Exists(dir))
    {
        Directory.CreateDirectory(dir);
    }
}

// 创建默认验证码图片
string defaultCaptchaPath = Path.Combine(webRootPath, "static", "default-captcha.jpg");
if (!Directory.Exists(Path.GetDirectoryName(defaultCaptchaPath)))
{
    Directory.CreateDirectory(Path.GetDirectoryName(defaultCaptchaPath));
}

// 如果默认验证码图片不存在，使用一个简单的字节数组创建一个
if (!File.Exists(defaultCaptchaPath))
{
    // 这只是一个示例，实际项目中应该使用真实的图片
    byte[] defaultImageBytes = new byte[] 
    { 
        0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 
        0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43, 
        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC2, 0x00, 0x0B, 0x08, 0x00, 0x01, 0x00, 
        0x01, 0x01, 0x01, 0x11, 0x00, 0xFF, 0xC4, 0x00, 0x14, 0x10, 0x01, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0xFF, 0xDA, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x3F, 
        0x10, 0xFF, 0xD9
    };
    File.WriteAllBytes(defaultCaptchaPath, defaultImageBytes);
}

var app = builder.Build();

// 确保上传目录存在
var uploadsImagePath = Path.Combine(app.Environment.WebRootPath, "uploads", "images");
if (!Directory.Exists(uploadsImagePath))
{
    Directory.CreateDirectory(uploadsImagePath);
}

var uploadsCaptchaPath = Path.Combine(app.Environment.WebRootPath, "captcha");
if (!Directory.Exists(uploadsCaptchaPath))
{
    Directory.CreateDirectory(uploadsCaptchaPath);
}

var uploadsReportsPath = Path.Combine(app.Environment.WebRootPath, "uploads", "reports");
if (!Directory.Exists(uploadsReportsPath))
{
    Directory.CreateDirectory(uploadsReportsPath);
}

// 配置异常处理中间件
app.UseExceptionHandler(errorApp =>
{
    errorApp.Run(async context =>
    {
        context.Response.StatusCode = 500;
        context.Response.ContentType = "application/json";
        
        var error = context.Features.Get<Microsoft.AspNetCore.Diagnostics.IExceptionHandlerFeature>();
        if (error != null)
        {
            var exception = error.Error;
            
            // 记录错误
            var logger = context.RequestServices.GetService<ILogger<Program>>();
            logger?.LogError(exception, "An unhandled exception occurred.");
            
            // 返回错误信息
            await context.Response.WriteAsJsonAsync(new
            {
                StatusCode = 500,
                Message = "An error occurred. Please try again later.",
                Details = exception.Message,
                StackTrace = app.Environment.IsDevelopment() ? exception.StackTrace : null
            });
        }
    });
});

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
    
    // 开发环境下允许所有来源的跨域请求
    app.UseCors("AllowAll");
}
else
{
    // 生产环境下使用更严格的跨域策略
    app.UseCors("ProductionCors");
    
    app.UseHsts();
}

// 使用静态文件中间件，用于验证码图片和上传文件的访问
app.UseStaticFiles();

app.UseHttpsRedirection();
app.UseRouting(); // 添加路由中间件
app.UseAuthentication();
app.UseAuthorization();

// 确保验证码图片目录存在
var captchaDir = Path.Combine(app.Environment.WebRootPath ?? Path.Combine(Directory.GetCurrentDirectory(), "wwwroot"), "captcha");
if (!Directory.Exists(captchaDir))
{
    Directory.CreateDirectory(captchaDir);
}

app.MapControllers();

app.Run();
